import { vnode } from './vmode'
import { createElement } from './createElement'
export function patch(oldVnode, newVnode) {
    // 判断第一个参数是否为虚拟dom
    if (!oldVnode.sel) {
        oldVnode = vnode(oldVnode.tagName.toLowerCase(), {}, [], undefined, oldVnode);
    }

    //判断是否同一节点
    if (oldVnode.sel == newVnode.sel && oldVnode.key == newVnode.key) {
        console.log("同一节点");
        if (oldVnode == newVnode) return;
        if (newVnode.text != undefined && (newVnode.children == undefined || newVnode.children.length == 0)) {
            //新节点有text属性
            if (newVnode.text == oldVnode.text) return;
            oldVnode.elm.innerText = newVnode.text;
        } else {
            //新节点无text属性
            if (oldVnode.text != undefined && (oldVnode.children == undefined || oldVnode.children.length == 0)) {
                //老节点有text
                var newDom = createElement(newVnode);
                //清空oldVnode的text属性
                oldVnode.elm.innerHTML = null;
                //追加newVnode的child到dom中
                for (let i = 0; i < newVnode.children.length; i++) {
                    const dom = createElement(newVnode.children[i]);
                    oldVnode.elm.appendChild(dom);
                }
            } else {
                //老节点无text
                patchSameVnode(oldVnode, newVnode);
            }
        }
    } else {
        let newVnodeElm = createElement(newVnode);
        //插入到老节点之前
        if (oldVnode.elm.parentNode && newVnodeElm) {
            oldVnode.elm.parentNode.insertBefore(newVnodeElm, oldVnode.elm);
        }
        //删除老节点
        oldVnode.elm.parentNode.removeChild(oldVnode.elm);
    }
}
/**
 * 遍历同一节点
 * @param {*} oldVnode 
 * @param {*} newVnode 
 * @returns 
 */
export function patchSameVnode(oldVnode, newVnode) {
    if (oldVnode == newVnode) return;
    if (newVnode.text != undefined && (newVnode.children == undefined || newVnode.children.length == 0)) {
        //新节点有text属性
        if (newVnode.text == oldVnode.text) return;
        oldVnode.elm.innerText = newVnode.text;
    } else {
        //新节点无text属性
        if (oldVnode.text != undefined && (oldVnode.children == undefined || oldVnode.children.length == 0)) {
            //老节点有text
            var newDom = createElement(newVnode);
            //清空oldVnode的text属性
            oldVnode.elm.innerHTML = null;
            //追加newVnode的child到dom中
            for (let i = 0; i < newVnode.children.length; i++) {
                const dom = createElement(newVnode.children[i]);
                oldVnode.elm.appendChild(dom);
            }
        } else {
            //老节点无text
            updateChildern(oldVnode.elm, oldVnode.children, newVnode.children);

        }
    }
}

/**
 * 更新对比新老childern
 * @param {*} parentElm 
 * @param {*} oldCh 
 * @param {*} newCh 
 */
export function updateChildern(parentElm, oldCh, newCh) {
    console.log('我是updateChildren');
    console.log(oldCh, newCh);
    //下标号
    let oldStartIdx = 0,
        oldEndIdx = oldCh.length - 1,
        newStartIdx = 0,
        newEndIdx = newCh.length - 1;
    //节点
    let oldStartVnode = oldCh[oldStartIdx],
        oldEndVnode = oldCh[oldEndIdx],
        newStartVnode = newCh[newStartIdx],
        newEndVnode = newCh[newEndIdx];

    let keyMap = null;

    //遍历
    while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
        //略过已经加undefined标记的东西
        if (!oldStartVnode || !oldCh[oldStartIdx]) {
            oldStartVnode = oldCh[++oldStartIdx]
        } else if (!oldEndVnode || !oldCh[oldEndIdx]) {
            oldEndVnode = oldCh[--oldEndIdx]
        } else if (!newStartVnode || !newCh[newStartIdx]) {
            newStartVnode = newCh[++newStartIdx]
        } else if (!newEndVnode || !newCh[newEndIdx]) {
            newEndVnode = newCh[--newEndIdx]
        } else if (checkSameVnode(oldStartVnode, newStartVnode)) {
            //新前与旧前
            console.log('1新前与旧前命中');
            patchSameVnode(oldStartVnode, newStartVnode);
            oldStartVnode = oldCh[++oldStartIdx];
            newStartVnode = newCh[++newStartIdx];
        } else if (checkSameVnode(oldEndVnode, newEndVnode)) {
            //新后与旧后
            console.log('2新后与旧后命中');
            patchSameVnode(oldEndVnode, newEndVnode);
            oldEndVnode = oldCh[--oldEndIdx];
            newEndVnode = newCh[--newEndIdx];
        } else if (checkSameVnode(oldStartVnode, newEndVnode)) {
            //新后与旧前
            console.log('3新后与旧前命中');
            patchSameVnode(oldStartVnode, newEndVnode);
            //3新后与旧前命中，移动节点，移动新前指向的这个节点到老节点的旧后的后面
            parentElm.insertBefore(oldStartVnode.elm, oldEndVnode.elm.nextSibling)
            oldStartVnode = oldCh[++oldStartIdx];
            newEndVnode = newCh[--newEndIdx];
        } else if (checkSameVnode(oldEndVnode, newStartVnode)) {
            //新前与旧后
            console.log('4新前与旧后命中');
            patchSameVnode(oldEndVnode, newStartVnode);
            //4新前与旧后命中，移动节点，移动新前指向的这个节点到老节点的旧后的前面
            parentElm.insertBefore(oldEndVnode.elm, oldStartVnode.elm)
            oldEndVnode = oldCh[--oldEndIdx];
            newStartVnode = newCh[++newStartIdx];
        } else {
            //1234都没找到
            //keyMap缓存
            if (!keyMap) {
                keyMap = {};
                for (let i = oldStartIdx; i <= oldEndIdx; i++) {
                    if (oldCh[i]) {
                        const key = oldCh[i].key;
                        keyMap[key] = i;
                    }

                }
            }
            console.log(keyMap);
            //寻找newStartIdx下标这项在keyMap中的位置
            const idxInOld = keyMap[newStartVnode.key];
            console.log(idxInOld);

            if (idxInOld == undefined) {
                //表示一个全新项
                //newStartVnode创建为dom
                parentElm.insertBefore(createElement(newStartVnode), oldStartVnode.elm)
            } else {
                //不是全新项，而是移动
                const elmToMove = oldCh[idxInOld];
                //判断是否为节点
                if (elmToMove && elmToMove.elm.nodeType == 1) {
                    patchSameVnode(elmToMove, newStartVnode);
                    //把这项设置为undefined
                    oldCh[idxInOld] = undefined;
                    //移动
                    parentElm.insertBefore(elmToMove.elm, oldStartVnode.elm);
                }

            }
            newStartVnode = newCh[++newStartIdx];
        }
    }

    //循环结束还有剩余的，循环结束start还是比end小
    if (newStartIdx <= newEndIdx) {
        console.log('new还有剩余的未处理');
        // const before = newCh[newEndIdx + 1] == null ? null : newCh[newEndIdx + 1].elm;
        // console.log(before);
        for (let i = newStartIdx; i <= newEndIdx; i++) {
            //bug待处理
            parentElm.insertBefore(createElement(newCh[i]), oldCh[oldStartIdx].elm);
        }
    } else {
        //old还有剩余的，删除old剩余节点
        for (let i = oldStartIdx; i <= oldEndIdx; i++) {
            if (oldCh[i]) {
                parentElm.removeChild(oldCh[i].elm);
            }
        }
    }


}

function checkSameVnode(a, b) {
    return a.sel == b.sel && a.key == b.key;
}